#include "mybitmap.h"
#include <stdlib.h>
#include <android/log.h>
#define  LOG_TAG    "prehanding"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#ifdef __cplusplus
extern "C" {
#endif

HistoryStack* historyStack = NULL;
HistoryNode* peekHistory()
{
	LOGI("peekHistory");
	if(NULL == historyStack) return NULL;
	return historyStack->header;

}
HistoryNode* popHistory()
{
 	LOGI("popHistory");
	if(NULL == historyStack) return NULL;
	HistoryNode* ret = historyStack->header;
	historyStack->header = ret->next;
	return ret;
}
uint32_t pushHistory(HistoryNode* node)
{
	LOGI("pushHistory");
	if(NULL == historyStack||NULL == node) return -1;
	
	node->pre = NULL;
	node->next = historyStack->header;
	if(NULL != historyStack->header)
	historyStack->header->pre = node;
	historyStack->header = node;
	(historyStack->depth)++;
	return historyStack->depth;
}
void emptyHistory()
{
	LOGI("emptyHistory");	
	if(NULL == historyStack) return;
	historyStack->header = NULL;
	historyStack->depth = 0;
	
}

int graying(float rRate,float gRate,float bRate)
{
	int ret = 0;
	HistoryNode* node = peekHistory();
	if(NULL == node)return;
	Bitmap* oldBitmap;
	Bitmap* newBitmap;
	uint32_t w;
	uint32_t h;
	if(OP_TYPE_GRAYING != node->op_type)
	{
		oldBitmap = node->bitmap;
		newBitmap = (Bitmap*)malloc(sizeof(Bitmap));
		newBitmap->pixels = (unsigned char*)malloc(sizeof(unsigned char)*w*h);
		w = oldBitmap->width;
		h = oldBitmap->height; 
		newBitmap->width = w;
		newBitmap->height = h;
		newBitmap->format = BITMAP_FORMAT_A_8;
		newBitmap->unpack = unpack_a_8;
		HistoryNode* newNode = (HistoryNode*)malloc(sizeof(HistoryNode));
	        newNode->bitmap = newBitmap;
		newNode->op_type = OP_TYPE_GRAYING;
        	pushHistory(newNode);
		ret = -1;
	}else{
		oldBitmap = node->next->bitmap;
		newBitmap = node->bitmap;
		w = oldBitmap->width;
		h = oldBitmap->height; 
	}
	unsigned char* oldp = oldBitmap->pixels;
	unsigned char* newp = newBitmap->pixels;
	int i = 0;
	int j = 0;
	for(i = 0;i<h ;i++)
	{	
		for(j= 0; j<w; j++)
		{
			unsigned char a,r,g,b;
                        int offset = bitmap->unpack(oldp,&a,&r,&g,&b);
                        oldp += offset;

			*newp = rRate*r+gRate*g+bRate*b;
			newp++;
		}
	}	
	return ret;
}

int binaryzation(int theshold)
{
	int ret = 0;
        HistoryNode* node = peekHistory();
        if(NULL == node)return;
        Bitmap* oldBitmap;
        Bitmap* newBitmap;
	uint32_t w;
	uint32_t h;
        if(OP_TYPE_BINARYZATION != node->op_type)
        {
                oldBitmap = node->bitmap;
                newBitmap = (Bitmap*)malloc(sizeof(Bitmap));
                newBitmap->pixels = (unsigned char*)malloc(sizeof(unsigned char)*w*h);
		w = oldBitmap->width;
		h = oldBitmap->height; 
                newBitmap->width = w;
                newBitmap->height = h;
		newBitmap->format = BITMAP_FORMAT_A_8;
                newBitmap->unpack = unpack_a_8;
                HistoryNode* newNode = (HistoryNode*)malloc(sizeof(HistoryNode));
                newNode->bitmap = newBitmap;
                newNode->op_type = OP_TYPE_GRAYING;
                pushHistory(newNode);
                ret = -1;
        }else{
                oldBitmap = node->next->bitmap;
                newBitmap = node->bitmap;
		w = oldBitmap->width;
		h = oldBitmap->height; 
        }
        unsigned char* oldp = oldBitmap->pixels;
        unsigned char* newp = newBitmap->pixels;
        int i = 0;
        int j = 0;
        for(i = 0;i<h ;i++)
        {
                for(j= 0; j<w; j++)
                {
                        unsigned char a,r,g,b;
                        int offset = bitmap->unpack(oldp,&a,&r,&g,&b);
		 	oldp += offset;
			if(r > theshold)
			{
				*newp = 255;
			}else{
				*newp = 0;
			}
	
                        newp++;
                }
        }
        return ret;
                          
}

#ifdef __cplusplus
}
#endif
